package com.javaDemo.ti;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

/**
 * 有三个线程，线程一只打印t1，线程二只打印t2，线程三只打印t3，输出到三个文件，
 * 第一个文件的打印顺序是t1 t2 t3 。。。第二个是t2 t3 t1 。。。 第三个是t3 t1 t2
 *
 * 使用notify实现
 */
public class DemoTest {


  /**
   * 次数标识，用来区分那个线程打印
   */
  private static volatile int count = 0;

  private static Object lock = new Object();



  private static File fileA = new File("/Users/csy/demo/fileA.txt");
  private static File fileB = new File("/Users/csy/demo/fileB.txt");
  private static File fileC = new File("/Users/csy/demo/fileC.txt");

  public static void main(String[] args) {
    try {
      fileA.createNewFile();
      fileB.createNewFile();
      fileC.createNewFile();
      BufferedWriter bufferedWriterA = new BufferedWriter(new FileWriter(fileA,true));
      BufferedWriter bufferedWriterB = new BufferedWriter(new FileWriter(fileB,true));
      BufferedWriter bufferedWriterC = new BufferedWriter(new FileWriter(fileC,true));

      PrintT1Thread printT1Thread = new PrintT1Thread();
      printT1Thread.bufferedWriterA = bufferedWriterA;
      printT1Thread.bufferedWriterB = bufferedWriterB;
      printT1Thread.bufferedWriterC = bufferedWriterC;

      PrintT2Thread printT2Thread = new PrintT2Thread();
      printT2Thread.bufferedWriterA = bufferedWriterA;
      printT2Thread.bufferedWriterB = bufferedWriterB;
      printT2Thread.bufferedWriterC = bufferedWriterC;

      PrintT3Thread printT3Thread = new PrintT3Thread();
      printT3Thread.bufferedWriterA = bufferedWriterA;
      printT3Thread.bufferedWriterB = bufferedWriterB;
      printT3Thread.bufferedWriterC = bufferedWriterC;


      new Thread(printT1Thread).start();
      new Thread(printT2Thread).start();
      new Thread(printT3Thread).start();
    } catch (IOException e) {
      e.printStackTrace();
    }

  }


  static class PrintT1Thread implements Runnable {

    BufferedWriter bufferedWriterA ;
    BufferedWriter bufferedWriterB ;
    BufferedWriter bufferedWriterC ;

    @Override
    public void run() {
      while (true){
        synchronized (lock) {
          try {
            if (count % 3 == 0) {
              bufferedWriterA.write("t1");
              bufferedWriterA.flush();
              if (count != 0) {
                bufferedWriterB.write("t1");
                bufferedWriterC.write("t1");
                bufferedWriterB.flush();
                bufferedWriterC.flush();
              }
              count++;

              lock.notifyAll();

            } else {
              lock.wait();
            }
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
    }
  }


  static class PrintT2Thread implements Runnable {

    BufferedWriter bufferedWriterA ;
    BufferedWriter bufferedWriterB ;
    BufferedWriter bufferedWriterC ;

    @Override
    public void run() {
      while (true){
        synchronized (lock) {
          try {
            if (count % 3 == 1) {
              bufferedWriterA.write("t2");
              bufferedWriterB.write("t2");
              bufferedWriterA.flush();
              bufferedWriterB.flush();

              if (count > 1) {
                bufferedWriterC.write("t2");
                bufferedWriterC.flush();
              }
              count++;
              lock.notifyAll();
            } else {
              lock.wait();
            }
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
    }
  }


  static class PrintT3Thread implements Runnable {

    BufferedWriter bufferedWriterA ;
    BufferedWriter bufferedWriterB ;
    BufferedWriter bufferedWriterC ;

    @Override
    public void run() {
      while (true){
        synchronized (lock) {
          try {
            if (count % 3 == 2) {
              bufferedWriterA.write("t3");
              bufferedWriterB.write("t3");
              bufferedWriterC.write("t3");
              bufferedWriterA.flush();
              bufferedWriterB.flush();
              bufferedWriterC.flush();
              count++;
              lock.notifyAll();
            } else {
              lock.wait();
            }
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
    }
  }
}
